package jupitermouse.site.juc.demo.aqs.reentrantlock;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 *     ReentrantLock重入锁使用
 * </p>
 *
 * @author jupiter
 */
public class ReentrantLockApp {

    private ReentrantLock reLock = new ReentrantLock();

    private Object mutex = new Object();

     void method(){
        reLock.lock();
        try {
            System.err.println("当前线程: " + Thread.currentThread().getName() + "进入...");
            Thread.sleep(2000);
            System.err.println("当前线程: " + Thread.currentThread().getName() + "退出...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            reLock.unlock();
        }
    }

    static void useLock(Method method){
         ReentrantLockApp app = new ReentrantLockApp();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    method.invoke(app);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }, "t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    method.invoke(app);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }, "t2");

        t1.start();
        t2.start();

    }

    void methodObj() throws InterruptedException {
        synchronized (mutex){
            System.err.println("当前线程: " + Thread.currentThread().getName() + "进入...");
            Thread.sleep(2000);
            System.err.println("当前线程: " + Thread.currentThread().getName() + "退出...");
        }
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method method = ReentrantLockApp.class.getDeclaredMethod("method");
//        Method method = ReentrantLockApp.class.getDeclaredMethod("methodObj");

        useLock(method);
    }
}
